package cn.sc.summer.mybatis.strategy.basestage;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.sc.summer.mybatis.constant.TableResource;
import cn.sc.summer.mybatis.enums.TableUpdateStage;
import cn.sc.summer.mybatis.model.DataSourceX;
import cn.sc.summer.mybatis.model.TableXInfo;
import cn.sc.summer.mybatis.table.execute.Execute;
import cn.sc.summer.constant.mybatisplus.datasource.TableInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.ArrayList;
import java.util.List;

/**
 * 类名：执行策略信息
 *
 * @author a-xin
 * @date 2024/8/29 13:01
 */
@Slf4j
public abstract class ExeCuteStage implements Execute {

    private static final long serialVersionUID = 8417053955351923074L;

    public static TableUpdateStage TABLE_STAGE = TableUpdateStage.ADD;

    /**
     * 执行更新
     *
     * @param dataSourceX 数据源信息
     * @param comparison  对比信息
     * @param event       执行事件
     */
    public void update(DataSourceX dataSourceX, Comparison comparison, Event event, SqlUtil sqlUtil) {
        String dataSourceName = dataSourceX.getDataSourceName().toLowerCase();
        if (CharSequenceUtil.isBlank(dataSourceName)) {
            throw new IllegalArgumentException("The data source information is incorrect!");
        }
        String supports = comparison.getSupports();
        if (!event.getSupports().equals(supports) || !sqlUtil.getSupports().equals(supports)) {
            throw new IllegalArgumentException("Parser, executor, SQL parsing type exceptions!");
        }
        List<TableInfo> tableInfos = TableResource.DATASOURCE_TABLE_INFO.getOrDefault(dataSourceName, new ArrayList<>());
        List<TableXInfo> tableXInfos = TableResource.TABLE_INFO.getOrDefault(dataSourceName, new ArrayList<>());
        Comparison.TABLE_INFOS.clear();
        Comparison.TABLE_X_INFOS.clear();
        if (CollUtil.isNotEmpty(tableInfos)) {
            Comparison.TABLE_INFOS.addAll(tableInfos);
        }
        if (CollUtil.isNotEmpty(tableXInfos)) {
            Comparison.TABLE_X_INFOS.addAll(tableXInfos);
        }
        if (CollUtil.isNotEmpty(Comparison.TABLE_X_INFOS) && CollUtil.isNotEmpty(Comparison.TABLE_INFOS)) {
            this.executeTable(dataSourceX, comparison, event, sqlUtil);
            this.executeColumn(dataSourceX, comparison, event, sqlUtil);
            this.executePrimaryKey(dataSourceX, comparison, event, sqlUtil);
        }
    }

    /**
     * 执行数据源表主键信息
     *
     * @param dataSourceX 数据源信息
     * @param comparison  对比信息
     * @param event       执行事件
     * @param sqlUtil     sql解析工具类
     */
    public void executePrimaryKey(DataSourceX dataSourceX, Comparison comparison, Event event, SqlUtil sqlUtil) {
        event.setJdbcTemplate(dataSourceX, sqlUtil);
        event.updatePrimaryId(comparison.getPrimaryKey(new JdbcTemplate(dataSourceX)));
    }

    /**
     * 执行数据源表信息更新
     *
     * @param dataSourceX 数据源信息
     * @param comparison  对比信息
     * @param event       执行事件
     * @param sqlUtil     sql解析工具类
     */
    public void executeTable(DataSourceX dataSourceX, Comparison comparison, Event event, SqlUtil sqlUtil) {
        event.setJdbcTemplate(dataSourceX, sqlUtil);
        event.addTable(comparison.getAddTable());
        switch (TABLE_STAGE) {
            case UPDATE:
                event.updateTable(comparison.getUpdateTable());
                break;
            case DEL:
                event.updateTable(comparison.getUpdateTable());
                event.delTable(comparison.getDeleteTable());
                break;
            case ADD:
            default:
                break;
        }
    }

    /**
     * 执行数据源表字段信息更新
     *
     * @param dataSourceX 数据源信息
     * @param comparison  对比信息
     * @param event       执行事件
     * @param sqlUtil     sql解析工具类
     */
    public void executeColumn(DataSourceX dataSourceX, Comparison comparison, Event event, SqlUtil sqlUtil) {
        event.setJdbcTemplate(dataSourceX, sqlUtil);
        event.addColumn(comparison.getAddColumn());
        switch (TABLE_STAGE) {
            case UPDATE:
                event.updateColumn(comparison.getUpdateColumn());
                break;
            case DEL:
                event.updateColumn(comparison.getUpdateColumn());
                event.delColumn(comparison.getDeleteColumn());
                break;
            case ADD:
            default:
                break;
        }
    }

}
